package org.dromara.datacheck.service.impl.jst;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.datacheck.domain.bo.JstAndJDTableDataEntryBo;
import org.dromara.datacheck.domain.bo.jst.ConsignmentBusinessDifferenceBo;
import org.dromara.datacheck.domain.bo.jst.JstPurchaseEnterWarehouseOrderBo;
import org.dromara.datacheck.domain.jd.JdPurchaseEnterWarehouseOrder;
import org.dromara.datacheck.domain.jst.JstPurchaseEnterWarehouseOrder;
import org.dromara.datacheck.domain.vo.jd.JdPurchaseEnterWarehouseOrderVo;
import org.dromara.datacheck.domain.vo.jst.JstPurchaseEnterWarehouseOrderVo;
import org.dromara.datacheck.mapper.jd.JdPurchaseEnterWarehouseOrderMapper;
import org.dromara.datacheck.mapper.jst.JstPurchaseEnterWarehouseOrderMapper;
import org.dromara.datacheck.service.jst.IJstPurchaseEnterWarehouseOrderService;
import org.dromara.datacheck.util.MyUtil;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 聚水潭-采购入库单Service业务层处理
 *
 * @author 刘武贵
 * @date 2024-09-08
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class JstPurchaseEnterWarehouseOrderServiceImpl implements IJstPurchaseEnterWarehouseOrderService {

    private final JstPurchaseEnterWarehouseOrderMapper baseMapper;

    @Resource
    private JdPurchaseEnterWarehouseOrderMapper jdPurchaseEnterWarehouseOrderMapper;

    /**
     * 查询聚水潭-采购入库单
     *
     * @param id 主键
     * @return 聚水潭-采购入库单
     */
    @Override
    public JstPurchaseEnterWarehouseOrderVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询聚水潭-采购入库单列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 聚水潭-采购入库单分页列表
     */
    @Override
    public TableDataInfo<JstPurchaseEnterWarehouseOrderVo> queryPageList(JstPurchaseEnterWarehouseOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<JstPurchaseEnterWarehouseOrder> lqw = buildQueryWrapper(bo);
        Page<JstPurchaseEnterWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的聚水潭-采购入库单列表
     *
     * @param bo 查询条件
     * @return 聚水潭-采购入库单列表
     */
    @Override
    public List<JstPurchaseEnterWarehouseOrderVo> queryList(JstPurchaseEnterWarehouseOrderBo bo) {
        LambdaQueryWrapper<JstPurchaseEnterWarehouseOrder> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 构建查询包装器
     *
     * @param bo 入库单业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     *
     * 该方法根据传入的入库单业务对象bo中的属性值构建一个LambdaQueryWrapper对象，
     * 用于在数据库查询时指定各种查询条件。每个属性（如入库单号、仓库名称等）
     * 都对应一个查询条件，只有当业务对象中的属性值不为空时，才会添加到查询条件中。
     */
    private LambdaQueryWrapper<JstPurchaseEnterWarehouseOrder> buildQueryWrapper(JstPurchaseEnterWarehouseOrderBo bo) {
        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper对象，用于构建查询条件
        LambdaQueryWrapper<JstPurchaseEnterWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 根据业务对象的属性值添加查询条件，只有当属性值不为空时才添加
        lqw.eq(StringUtils.isNotBlank(bo.getEnterWarehouseNumber()), JstPurchaseEnterWarehouseOrder::getEnterWarehouseNumber, bo.getEnterWarehouseNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getOperatorWarehouseOwner()), JstPurchaseEnterWarehouseOrder::getOperatorWarehouseOwner, bo.getOperatorWarehouseOwner());
        lqw.like(StringUtils.isNotBlank(bo.getWarehouseName()), JstPurchaseEnterWarehouseOrder::getWarehouseName, bo.getWarehouseName());
        lqw.like(StringUtils.isNotBlank(bo.getSupplierName()), JstPurchaseEnterWarehouseOrder::getSupplierName, bo.getSupplierName());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstPurchaseEnterWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getPurchaseOrderNumber()), JstPurchaseEnterWarehouseOrder::getPurchaseOrderNumber, bo.getPurchaseOrderNumber());
        lqw.eq(bo.getBillCreateTime() != null, JstPurchaseEnterWarehouseOrder::getBillCreateTime, bo.getBillCreateTime());
        lqw.eq(bo.getEnterWarehouseDate() != null, JstPurchaseEnterWarehouseOrder::getEnterWarehouseDate, bo.getEnterWarehouseDate());
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstPurchaseEnterWarehouseOrder::getShopName, bo.getShopName());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstPurchaseEnterWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getColorSku()), JstPurchaseEnterWarehouseOrder::getColorSku, bo.getColorSku());
        lqw.eq(bo.getQuantity() != null, JstPurchaseEnterWarehouseOrder::getQuantity, bo.getQuantity());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstPurchaseEnterWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstPurchaseEnterWarehouseOrder::getId, idsList);
        }
        // 返回构建好的查询包装器
        return lqw;
    }

    /**
     * 新增聚水潭-采购入库单
     *
     * @param bo 聚水潭-采购入库单
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(JstPurchaseEnterWarehouseOrderBo bo) {
        JstPurchaseEnterWarehouseOrder add = MapstructUtils.convert(bo, JstPurchaseEnterWarehouseOrder.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改聚水潭-采购入库单
     *
     * @param bo 聚水潭-采购入库单
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(JstPurchaseEnterWarehouseOrderBo bo) {
        JstPurchaseEnterWarehouseOrder update = MapstructUtils.convert(bo, JstPurchaseEnterWarehouseOrder.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(JstPurchaseEnterWarehouseOrder entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除聚水潭-采购入库单信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    /**
     * 查询聚水潭-采购入库单列表所有数据
     *
     * @return 聚水潭-采购入库单列表
     */
    @Override
    public List<JstPurchaseEnterWarehouseOrder> queryAll() {
        return baseMapper.selectList(null);
    }

    /**
     * 清空聚水潭-采购入库单列表所有数据
     *
     * @return 聚水潭-采购入库单列表
     */
    @Override
    public Integer deleteAll() {
        return baseMapper.delete(new QueryWrapper<>());
    }

    /**
     * 分页查询聚水潭-采购入库单列表
     * 业务查询条件：根据operator_warhouse_owner名称为国内工厂在途仓和深圳/东莞仓查询
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 聚水潭-采购入库单分页列表
     */
    @Override
    public TableDataInfo<JstPurchaseEnterWarehouseOrderVo> queryPageListByDongGuanAndGuoNei(JstPurchaseEnterWarehouseOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<JstPurchaseEnterWarehouseOrder> lqw = buildQueryWrapperByDongGuanAndGuoNei(bo);
        Page<JstPurchaseEnterWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 构建查询包装器（东莞和国内）
     * 此方法根据传入的业务对象（BO）中的参数构建一个查询包装器，
     * 用于在数据库查询时过滤结果
     *
     * @param bo 业务对象，包含查询参数
     * @return 构建的LambdaQueryWrapper用于后续的数据库查询
     */
    private LambdaQueryWrapper<JstPurchaseEnterWarehouseOrder> buildQueryWrapperByDongGuanAndGuoNei(JstPurchaseEnterWarehouseOrderBo bo) {
        // 获取额外参数，可能用于查询的扩展或动态部分
        Map<String, Object> params = bo.getParams();
        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstPurchaseEnterWarehouseOrder> lqw = Wrappers.lambdaQuery();
        // 根据业务对象的属性值添加查询条件，只有当属性值不为空时才添加
        lqw.eq(StringUtils.isNotBlank(bo.getEnterWarehouseNumber()), JstPurchaseEnterWarehouseOrder::getEnterWarehouseNumber, bo.getEnterWarehouseNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getOperatorWarehouseOwner()), JstPurchaseEnterWarehouseOrder::getOperatorWarehouseOwner, bo.getOperatorWarehouseOwner());
        lqw.like(StringUtils.isNotBlank(bo.getWarehouseName()), JstPurchaseEnterWarehouseOrder::getWarehouseName, bo.getWarehouseName());
        lqw.like(StringUtils.isNotBlank(bo.getSupplierName()), JstPurchaseEnterWarehouseOrder::getSupplierName, bo.getSupplierName());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstPurchaseEnterWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getPurchaseOrderNumber()), JstPurchaseEnterWarehouseOrder::getPurchaseOrderNumber, bo.getPurchaseOrderNumber());
        lqw.eq(bo.getEnterWarehouseDate() != null, JstPurchaseEnterWarehouseOrder::getEnterWarehouseDate, bo.getEnterWarehouseDate());
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstPurchaseEnterWarehouseOrder::getShopName, bo.getShopName());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstPurchaseEnterWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getColorSku()), JstPurchaseEnterWarehouseOrder::getColorSku, bo.getColorSku());
        lqw.eq(bo.getQuantity() != null, JstPurchaseEnterWarehouseOrder::getQuantity, bo.getQuantity());
        lqw.eq(JstPurchaseEnterWarehouseOrder::getDataSign, "0");
        // 如果操作员仓库所有者不为空，则添加等于条件
        lqw.in(CollUtil.isNotEmpty(bo.getOperatorWarhouseOwnerList()), JstPurchaseEnterWarehouseOrder::getOperatorWarehouseOwner, bo.getOperatorWarhouseOwnerList());
        // 如果创建时间不为空，则添加等于条件
        lqw.eq(bo.getBillCreateTime() != null, JstPurchaseEnterWarehouseOrder::getBillCreateTime, bo.getBillCreateTime());
        // 如果入库日期不为空，则添加等于条件
        lqw.eq(bo.getEnterWarehouseDate() != null, JstPurchaseEnterWarehouseOrder::getEnterWarehouseDate, bo.getEnterWarehouseDate());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstPurchaseEnterWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        // 返回构建好的查询包装器
        return lqw;
    }

    /**
     * 查询聚水潭-采购入库单列表以及金蝶-采购入库单数据汇总（按日期汇总）
     */
    @Override
    public TableDataInfo<JstAndJDTableDataEntryBo> jstAndJdSumByDate() {
        List<JstAndJDTableDataEntryBo> jstAndJDTableDataEntryList =new ArrayList<>();
        JstAndJDTableDataEntryBo jstAndJDTableDataEntry = new JstAndJDTableDataEntryBo();
        // 1、查询两个平台数据
        // 1-1、查询聚水潭的数据
        LambdaQueryWrapper<JstPurchaseEnterWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        lqw1.in(JstPurchaseEnterWarehouseOrder::getOperatorWarehouseOwner, Arrays.asList("深圳/东莞仓", "国内工厂在途仓"));
        lqw1.eq(JstPurchaseEnterWarehouseOrder::getDataSign, "0");
        List<JstPurchaseEnterWarehouseOrderVo> jstPurchaseEnterWarehouseOrderList = baseMapper.selectVoList(lqw1);

        // 1-2、查询金蝶的数据
        LambdaQueryWrapper<JdPurchaseEnterWarehouseOrder> lqw2 = Wrappers.lambdaQuery();
        lqw2.in(JdPurchaseEnterWarehouseOrder::getWarehouseName, Arrays.asList("东莞仓", "国内在途仓"));
        lqw2.eq(JdPurchaseEnterWarehouseOrder::getReceiptStatus, "已审核");
        List<JdPurchaseEnterWarehouseOrderVo> jdPurchaseEnterWarehouseOrderList = jdPurchaseEnterWarehouseOrderMapper.selectVoList(lqw2);

        // 2、生成日期列表和处理日期
        // 2-1、生成日期列表，以聚水潭的最晚日期为截止日期取
        List<Date> dateList = jstPurchaseEnterWarehouseOrderList.stream()
            .sorted(Comparator.comparing(JstPurchaseEnterWarehouseOrderVo::getNewOrderDate))
            .map(JstPurchaseEnterWarehouseOrderVo::getNewOrderDate)
            .distinct()
            .collect(Collectors.toList());

        // 2-2、将日期列表转换为字符串列表
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
        List<String> dateStringList = dateList.stream()
            .map(date -> dateFormat.format(date))
            .collect(Collectors.toList());

        // 2-3、获取去重后的日期列表，并转换格式
        Set<String> formattedDateSet = dateStringList.stream()
            // 将字符串转换为 LocalDate 对象
            .map(MyUtil::parseToLocalDate)
            .sorted()
            .map(MyUtil::formatDateStringByLocalDate)
            .collect(Collectors.toSet());
        List<String> formattedDateList = new ArrayList<>(formattedDateSet);
        Collections.sort(formattedDateList, Comparator.naturalOrder());

        // 3、处理两个平台的日期
        // 3-1、处理聚水潭和金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jstCountMap = jstPurchaseEnterWarehouseOrderList.stream()
            .filter(order -> order.getNewOrderDate() != null)
            .sorted(Comparator.comparing(JstPurchaseEnterWarehouseOrderVo::getNewOrderDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringNoPadZero(dateFormat.format(order.getNewOrderDate())),
                Collectors.summingInt(JstPurchaseEnterWarehouseOrderVo::getQuantity)
            ));

        // 3-2、处理金蝶的数据里面的日期
        // key 为日期，value 为数量
        Map<String, Integer> jdCountMap = jdPurchaseEnterWarehouseOrderList.stream()
            .filter(order -> order.getEnterWarehouseDate() != null)
            .sorted(Comparator.comparing(JdPurchaseEnterWarehouseOrderVo::getEnterWarehouseDate))
            .collect(Collectors.groupingBy(
                order -> MyUtil.formatDateStringPadZero(order.getEnterWarehouseDate()),
                Collectors.summingInt(JdPurchaseEnterWarehouseOrderVo::getActualQuantity)
            ));

        // 4、构建形如<date1,日期>的key value对，这个是前端要求
        Map<String, String> dateMap = MyUtil.buildDateMap(formattedDateList);

        // 5、构建表格数据
        // 数据格式形如: "tableList": [
        //                {
        //                    "label": "金蝶",
        //                    "date1": 0,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 0,
        //                    "date8": 1822,
        //                    "date9": 0
        //                },
        //                {
        //                    "label": "聚水潭",
        //                    "date1": 2130,
        //                    "date2": 2,
        //                    "date3": 3420,
        //                    "date4": 179,
        //                    "date5": 449,
        //                    "date6": 922,
        //                    "date7": 1409,
        //                    "date8": 1822,
        //                    "date9": 1631
        //                },
        //                {
        //                    "label": "差异",
        //                    "date1": 2130,
        //                    "date2": 0,
        //                    "date3": 0,
        //                    "date4": 0,
        //                    "date5": 0,
        //                    "date6": 0,
        //                    "date7": 1409,
        //                    "date8": 0,
        //                    "date9": 1631
        //                }
        //            ]
        List<Map<String, Object>> resultList = new ArrayList<>();

        // 5-1、初始化三个 Map 来存储数据
        Map<String, Object> jdData = new LinkedHashMap<>();
        Map<String, Object> jstData = new LinkedHashMap<>();
        Map<String, Object> diffData = new LinkedHashMap<>();

        // 设置 label
        jdData.put("label", "金蝶");
        jstData.put("label", "聚水潭");
        diffData.put("label", "差异");

        // 5-2、遍历日期列表，填充数据
        int dateIndex = 1;
        for (String date : formattedDateList) {
            int jstCount = jstCountMap.getOrDefault(date, 0);
            int jdCount = jdCountMap.getOrDefault(date, 0);
            int diff = Math.abs(jstCount - jdCount);

            // 填充数据
            jdData.put("date" + dateIndex, jdCount);
            jstData.put("date" + dateIndex, jstCount);
            diffData.put("date" + dateIndex, diff);

            dateIndex++;
        }

        // 5-3、将三个 Map 添加到结果列表中
        resultList.add(jdData);
        resultList.add(jstData);
        resultList.add(diffData);
        // 5-4、设置表格数据
        jstAndJDTableDataEntry.setTableList(resultList);

        // 6、构建列数据
        // 数据格式形如:
        // [
        //                {
        //                    "label": "系统",
        //                    "prop": "label"
        //                },
        //                {
        //                    "label": "2024年07月31日",
        //                    "prop": "date1"
        //                },
        // ]
        List<Map<String, Object>> columnList = new ArrayList<>();
        // 6-1、添加 "系统" 列
        Map<String, Object> systemColumn = new LinkedHashMap<>();
        systemColumn.put("label", "系统");
        systemColumn.put("prop", "label");
        columnList.add(systemColumn);

        // 6-2、添加日期列
        for (int i = 0; i <formattedDateList.size()+1; i++) {
            Map<String, Object> dateColumn = new LinkedHashMap<>();
            // 可以根据需要修改日期格式，根据业务需要，这里先按照date1这样处理
            dateColumn.put("label", dateMap.get("date" + i));
            dateColumn.put("prop", "date" + i);
            columnList.add(dateColumn);
            dateIndex++;
        }
        // 6-3、设置表格数据
        jstAndJDTableDataEntry.setColumnList(columnList);
        jstAndJDTableDataEntryList.add(jstAndJDTableDataEntry);

        // 7、构建JSON，构建返回数据
        TableDataInfo<JstAndJDTableDataEntryBo> result = new TableDataInfo<>();
        result.setRows(jstAndJDTableDataEntryList);
        result.setMsg("查询成功");

        return result;
    }

    /**
     * 查询聚水潭-采购入库单列表（金蝶缺少的数据）
     * 业务查询条件：根据operator_warehouse_owner操作仓储方名称为国内工厂在途仓和深圳/东莞仓查询
     * 场景分类：1、采购流程（含委外）-东莞仓，国内在途仓
     *
     * @param bo
     * @param pageQuery
     */
    @Override
    public TableDataInfo<JstPurchaseEnterWarehouseOrderVo> listByDongGuanAndGuoNeiByJdDeficiency1(JstPurchaseEnterWarehouseOrderBo bo, PageQuery pageQuery) {
        // 计算1、采购流程（含委外）-东莞仓，国内在途仓场景差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculatePurchaseBusinessDifference1();
        LambdaQueryWrapper<JstPurchaseEnterWarehouseOrder> lqw = buildQueryWrapperByDongGuanAndGuoNeiByJdDeficiency1(bo, consignmentBusinessDifferenceBo);
        Page<JstPurchaseEnterWarehouseOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 计算1、采购流程（含委外）-东莞仓，国内在途仓场景业务差异数据
     */
    private ConsignmentBusinessDifferenceBo calculatePurchaseBusinessDifference1(){
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = new ConsignmentBusinessDifferenceBo();
        // 聚水潭所有入仓单号
        List<String> jstOrderNumberList = new ArrayList<>();
        // 金蝶所有单据编号
        List<String> jdOrderNumberList = new ArrayList<>();
        // 1、查询聚水潭采购入库单，取出所有入仓单号
        LambdaQueryWrapper<JstPurchaseEnterWarehouseOrder> lqw1 = Wrappers.lambdaQuery();
        lqw1.eq(JstPurchaseEnterWarehouseOrder::getDataSign, "0");
        lqw1.in(JstPurchaseEnterWarehouseOrder::getOperatorWarehouseOwner, Arrays.asList("深圳/东莞仓", "国内工厂在途仓"));
        List<JstPurchaseEnterWarehouseOrderVo> jstPurchaseEnterWarehouseOrderList = baseMapper.selectVoList(lqw1);
        if(CollUtil.isNotEmpty(jstPurchaseEnterWarehouseOrderList)){
            jstOrderNumberList = jstPurchaseEnterWarehouseOrderList.stream().map(JstPurchaseEnterWarehouseOrderVo::getEnterWarehouseNumber).toList();
        }

        // 2、查询金蝶采购入库单，取出所有单据编号分组
        LambdaQueryWrapper<JdPurchaseEnterWarehouseOrder> lqw2 = Wrappers.lambdaQuery();
        lqw2.in(JdPurchaseEnterWarehouseOrder::getWarehouseName, Arrays.asList("东莞仓", "国内在途仓"));
        List<JdPurchaseEnterWarehouseOrderVo> jdPurchaseEnterWarehouseOrderList = jdPurchaseEnterWarehouseOrderMapper.selectVoList(lqw2);
        if(CollUtil.isNotEmpty(jstPurchaseEnterWarehouseOrderList)){
            jdOrderNumberList = jdPurchaseEnterWarehouseOrderList.stream().map(JdPurchaseEnterWarehouseOrderVo::getPurchaseEnterNumber).toList();
        }

        // 3、数据比较以聚水潭的入仓单号为准，比较缺少的单据编号组成新的List<String>
        List<String> finalJdOrderNumberList = jdOrderNumberList;
        List<String> missingOrderNumbers = jstOrderNumberList.stream()
            .filter(jstOrderNumber -> !finalJdOrderNumberList.contains(jstOrderNumber))
            .collect(Collectors.toList());

        // 将缺失的单据编号设置到 ConsignmentBusinessDifferenceBo 对象中
        consignmentBusinessDifferenceBo.setReceiptNumberList(missingOrderNumbers);

        return consignmentBusinessDifferenceBo;

    }


    /**
     * 构建查询包装器（东莞和国内）
     * 此方法根据传入的业务对象（BO）中的参数构建一个查询包装器，
     * 用于在数据库查询时过滤结果
     *
     * @param bo 业务对象，包含查询参数
     * @return 构建的LambdaQueryWrapper用于后续的数据库查询
     */
    private LambdaQueryWrapper<JstPurchaseEnterWarehouseOrder> buildQueryWrapperByDongGuanAndGuoNeiByJdDeficiency1(JstPurchaseEnterWarehouseOrderBo bo,ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo ) {
        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 获取额外参数，可能用于查询的扩展或动态部分
        Map<String, Object> params = bo.getParams();
        // 初始化LambdaQueryWrapper，用于构建查询条件
        LambdaQueryWrapper<JstPurchaseEnterWarehouseOrder> lqw = Wrappers.lambdaQuery();
        // 根据业务对象的属性值添加查询条件，只有当属性值不为空时才添加
        lqw.eq(StringUtils.isNotBlank(bo.getEnterWarehouseNumber()), JstPurchaseEnterWarehouseOrder::getEnterWarehouseNumber, bo.getEnterWarehouseNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getOperatorWarehouseOwner()), JstPurchaseEnterWarehouseOrder::getOperatorWarehouseOwner, bo.getOperatorWarehouseOwner());
        lqw.like(StringUtils.isNotBlank(bo.getWarehouseName()), JstPurchaseEnterWarehouseOrder::getWarehouseName, bo.getWarehouseName());
        lqw.like(StringUtils.isNotBlank(bo.getSupplierName()), JstPurchaseEnterWarehouseOrder::getSupplierName, bo.getSupplierName());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstPurchaseEnterWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getPurchaseOrderNumber()), JstPurchaseEnterWarehouseOrder::getPurchaseOrderNumber, bo.getPurchaseOrderNumber());
        lqw.eq(bo.getEnterWarehouseDate() != null, JstPurchaseEnterWarehouseOrder::getEnterWarehouseDate, bo.getEnterWarehouseDate());
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstPurchaseEnterWarehouseOrder::getShopName, bo.getShopName());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstPurchaseEnterWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getColorSku()), JstPurchaseEnterWarehouseOrder::getColorSku, bo.getColorSku());
        lqw.eq(bo.getQuantity() != null, JstPurchaseEnterWarehouseOrder::getQuantity, bo.getQuantity());
        lqw.eq(JstPurchaseEnterWarehouseOrder::getDataSign, "0");
        // 如果操作员仓库所有者不为空，则添加等于条件
        lqw.in(CollUtil.isNotEmpty(bo.getOperatorWarhouseOwnerList()), JstPurchaseEnterWarehouseOrder::getOperatorWarehouseOwner, bo.getOperatorWarhouseOwnerList());
        // 如果创建时间不为空，则添加等于条件
        lqw.eq(bo.getBillCreateTime() != null, JstPurchaseEnterWarehouseOrder::getBillCreateTime, bo.getBillCreateTime());
        // 如果入库日期不为空，则添加等于条件
        lqw.eq(bo.getEnterWarehouseDate() != null, JstPurchaseEnterWarehouseOrder::getEnterWarehouseDate, bo.getEnterWarehouseDate());
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstPurchaseEnterWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstPurchaseEnterWarehouseOrder::getId, idsList);
        }
        // 根据入仓单号查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getReceiptNumberList()) && !boParams) {
            lqw.in(JstPurchaseEnterWarehouseOrder::getEnterWarehouseNumber, consignmentBusinessDifferenceBo.getReceiptNumberList());
        }

        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getReceiptNumberList()) && !boParams) {
            lqw.eq(JstPurchaseEnterWarehouseOrder::getEnterWarehouseNumber, 0);
        }


        // 返回构建好的查询包装器
        return lqw;
    }

    /**
     * 导出聚水潭-采购入库单列表（金蝶缺少的数据）
     *
     * @param bo
     */
    @Override
    public List<JstPurchaseEnterWarehouseOrderVo> queryListByDongguanAndGuoneiByJdDeficiency(JstPurchaseEnterWarehouseOrderBo bo) {
        // 计算1、采购流程（含委外）-东莞仓，国内在途仓场景差异数据
        ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo = this.calculatePurchaseBusinessDifference1();
        LambdaQueryWrapper<JstPurchaseEnterWarehouseOrder> lqw = buildQueryWrapperByDongguanAndGuoneiByJdDeficiency(bo, consignmentBusinessDifferenceBo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 构建查询包装器
     *
     * @param bo 入库单业务对象，包含查询参数
     * @return LambdaQueryWrapper 查询包装器，用于后续的条件查询
     *
     * 该方法根据传入的入库单业务对象bo中的属性值构建一个LambdaQueryWrapper对象，
     * 用于在数据库查询时指定各种查询条件。每个属性（如入库单号、仓库名称等）
     * 都对应一个查询条件，只有当业务对象中的属性值不为空时，才会添加到查询条件中。
     */
    private LambdaQueryWrapper<JstPurchaseEnterWarehouseOrder> buildQueryWrapperByDongguanAndGuoneiByJdDeficiency(JstPurchaseEnterWarehouseOrderBo bo,ConsignmentBusinessDifferenceBo consignmentBusinessDifferenceBo ) {
        // 检测bo的参数
        Boolean boParams = isAnyFieldNonEmpty(bo);

        // 获取可能的额外查询参数
        Map<String, Object> params = bo.getParams();

        // 初始化LambdaQueryWrapper对象，用于构建查询条件
        LambdaQueryWrapper<JstPurchaseEnterWarehouseOrder> lqw = Wrappers.lambdaQuery();

        // 根据业务对象的属性值添加查询条件，只有当属性值不为空时才添加
        lqw.eq(StringUtils.isNotBlank(bo.getEnterWarehouseNumber()), JstPurchaseEnterWarehouseOrder::getEnterWarehouseNumber, bo.getEnterWarehouseNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getOperatorWarehouseOwner()), JstPurchaseEnterWarehouseOrder::getOperatorWarehouseOwner, bo.getOperatorWarehouseOwner());
        lqw.like(StringUtils.isNotBlank(bo.getWarehouseName()), JstPurchaseEnterWarehouseOrder::getWarehouseName, bo.getWarehouseName());
        lqw.like(StringUtils.isNotBlank(bo.getSupplierName()), JstPurchaseEnterWarehouseOrder::getSupplierName, bo.getSupplierName());
        lqw.eq(StringUtils.isNotBlank(bo.getStyleNumber()), JstPurchaseEnterWarehouseOrder::getStyleNumber, bo.getStyleNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getPurchaseOrderNumber()), JstPurchaseEnterWarehouseOrder::getPurchaseOrderNumber, bo.getPurchaseOrderNumber());
        lqw.eq(bo.getBillCreateTime() != null, JstPurchaseEnterWarehouseOrder::getBillCreateTime, bo.getBillCreateTime());
        lqw.eq(bo.getEnterWarehouseDate() != null, JstPurchaseEnterWarehouseOrder::getEnterWarehouseDate, bo.getEnterWarehouseDate());
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), JstPurchaseEnterWarehouseOrder::getShopName, bo.getShopName());
        lqw.eq(StringUtils.isNotBlank(bo.getProductNumber()), JstPurchaseEnterWarehouseOrder::getProductNumber, bo.getProductNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getColorSku()), JstPurchaseEnterWarehouseOrder::getColorSku, bo.getColorSku());
        lqw.eq(bo.getQuantity() != null, JstPurchaseEnterWarehouseOrder::getQuantity, bo.getQuantity());
        lqw.eq(JstPurchaseEnterWarehouseOrder::getDataSign, "0");
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            lqw.between(JstPurchaseEnterWarehouseOrder::getNewOrderDate,
                params.get("beginTime"),
                params.get("endTime"));
        }
        if (StrUtil.isNotBlank(bo.getIds())) {
            List<Long> idsList =
                Arrays.stream(bo.getIds().split(","))
                    .map(String::trim)
                    .map(Long::parseLong)
                    .toList();
            lqw.in(JstPurchaseEnterWarehouseOrder::getId, idsList);
        }
        // 根据内入仓单号查询（查询金蝶缺少数据），差异数据bo对象不为空且bo参数为假就导出
        if (CollUtil.isNotEmpty(consignmentBusinessDifferenceBo.getReceiptNumberList()) && !boParams) {
            lqw.in(JstPurchaseEnterWarehouseOrder::getEnterWarehouseNumber, consignmentBusinessDifferenceBo.getReceiptNumberList());
        }

        // 解决bug的查询，如果没有差异数据，那就是期望列表没数据，就返回一个假数据，避免查询所有数据
        if (CollUtil.isEmpty(consignmentBusinessDifferenceBo.getReceiptNumberList()) && !boParams) {
            lqw.eq(JstPurchaseEnterWarehouseOrder::getEnterWarehouseNumber, 0);
        }

        // 返回构建好的查询包装器
        return lqw;
    }

    /**
     * 检查任意一个参数是否不为空，并设置布尔值
     * @return 如果任意一个参数不为空，则返回 true，否则返回 false
     */
    public boolean isAnyFieldNonEmpty(JstPurchaseEnterWarehouseOrderBo bo) {
        return bo.getId() != null ||
            bo.getEnterWarehouseNumber() != null && !bo.getEnterWarehouseNumber().isEmpty() ||
            bo.getOperatorWarehouseOwner() != null && !bo.getOperatorWarehouseOwner().isEmpty() ||
            bo.getWarehouseName() != null && !bo.getWarehouseName().isEmpty() ||
            bo.getSupplierName() != null && !bo.getSupplierName().isEmpty() ||
            bo.getStyleNumber() != null && !bo.getStyleNumber().isEmpty() ||
            bo.getPurchaseOrderNumber() != null && !bo.getPurchaseOrderNumber().isEmpty() ||
            bo.getBillCreateTime() != null && !bo.getBillCreateTime().isEmpty() ||
            bo.getEnterWarehouseDate() != null && !bo.getEnterWarehouseDate().isEmpty() ||
            bo.getShopName() != null && !bo.getShopName().isEmpty() ||
            bo.getProductNumber() != null && !bo.getProductNumber().isEmpty() ||
            bo.getColorSku() != null && !bo.getColorSku().isEmpty() ||
            bo.getQuantity() != null ||
            bo.getOperatorWarhouseOwnerList() != null && !bo.getOperatorWarhouseOwnerList().isEmpty() ||
            bo.getNewOrderDate() != null ||
            bo.getJdMaterialCode() != null && !bo.getJdMaterialCode().isEmpty() ||
            bo.getCompareDateToJd() != null && !bo.getCompareDateToJd().isEmpty();
    }

}
